package com.sjft.cloud.commons.swagger.config;

import com.sjft.cloud.commons.swagger.properties.SwaggerProperties;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.OAuthFlow;
import io.swagger.v3.oas.models.security.OAuthFlows;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;


@Configuration
@EnableConfigurationProperties(SwaggerProperties.class)
public class SwaggerConfig {

    @Bean
    public OpenAPI customOpenAPI(SwaggerProperties swaggerProperties) {
        return new OpenAPI()
                .servers(getServer(swaggerProperties))
                .components(components(swaggerProperties)).security(security(swaggerProperties))
                .info(new Info()
                        .title(swaggerProperties.getTitle())
                        .version(swaggerProperties.getVersion())
                        .contact(new Contact()
                                .name(swaggerProperties.getContact().getName())
                                .email(swaggerProperties.getContact().getEmail())
                                .url(swaggerProperties.getContact().getUrl())
                        )
                        .termsOfService(swaggerProperties.getTermsOfServiceUrl())
                        .description(swaggerProperties.getDescription())
                        .license(new License()
                                .name(swaggerProperties.getLicense())
                                .url(swaggerProperties.getLicenseUrl())));
    }

    private Components components(SwaggerProperties swaggerProperties) {
        return new Components().addSecuritySchemes(
                "OAUTH2", new SecurityScheme()
                        .description("OAUTH2")
                        .type(SecurityScheme.Type.OAUTH2)
                        .flows(new OAuthFlows()
                                .password(
                                        new OAuthFlow()
                                                .tokenUrl(swaggerProperties.getOAuth2().getTokenUrl())
                                                .scopes(swaggerProperties.getOAuth2().getScopes())
                                )
                        ).flows(new OAuthFlows()
                                .password(
                                        new OAuthFlow()
                                                .tokenUrl(swaggerProperties.getOAuth2().getTokenUrl())
                                                .scopes(swaggerProperties.getOAuth2().getScopes())
                                ))
        ).addSecuritySchemes("BearerToken",
                new SecurityScheme()
                        .type(SecurityScheme.Type.HTTP)
                        .description("http请求头token令牌")
                        .scheme("bearer")
                        .bearerFormat("AccessToken"));


    }


    private List<SecurityRequirement> security(SwaggerProperties swaggerProperties) {
        return components(swaggerProperties).getSecuritySchemes().keySet()
                .stream()
                .map(key -> new SecurityRequirement().addList(key))
                .collect(Collectors.toList());
    }

    public List<Server> getServer(SwaggerProperties swaggerProperties) {
        List<Server> list = new ArrayList();
        Server defaultServer = new Server();
        defaultServer.url("/");
        defaultServer.setDescription("default");
        list.add(defaultServer);
        list.add(swaggerProperties.getServer());
        return list;
    }

}
